package com.tool.cn.freemaker;

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.text.SimpleDateFormat;
import java.util.Date;

/**
 * jdbc驱动表  --> 模型类
 * @author wangzh
 * @date 2018年7月9日 下午12:18:16
 */
public class GenerateEntity {
	
	private static final String databases="ddp";
	private static final String URL = "jdbc:mysql://127.0.0.1:3306/"+databases+"?serverTimezone=UTC";
	private static final String NAME = "root";
	private static final String PASS = "wang";
	private static final String DRIVER = "com.mysql.cj.jdbc.Driver";

	private String packageOutPath = "com.generation.model";// 指定实体生成所在包的路径
	private String authorName = "Wangzh";// 作者名字
	private String tablename = "test";// 表名
	private String functionDetail = "测试表"; //功能描述
	private String copyright = "Copyright 2018. All Rights Reserved.";

	
	private static String targetClassPath = GenerateEntity.class.getResource("/").toString().replace("file:/", "");
	private String[] colnames; // 列名数组
	private String[] colTypes; // 列名类型数组
	private int[] colSizes; // 列名大小数组
	private boolean f_util = false; // 是否需要导入包java.util.*
	private boolean f_sql = false; // 是否需要导入包java.sql.*

	public GenerateEntity() {
		// 创建连接
		Connection con;
		// 查要生成实体类的表
		String sql = "select * from " + tablename;
		PreparedStatement pStemt = null;
		try {
			try {
				Class.forName(DRIVER);
			} catch (ClassNotFoundException e1) {
				e1.printStackTrace();
			}
			con = DriverManager.getConnection(URL, NAME, PASS);
			pStemt = con.prepareStatement(sql);
			ResultSetMetaData rsmd = pStemt.getMetaData();
			int size = rsmd.getColumnCount(); // 统计列
			colnames = new String[size];
			colTypes = new String[size];
			colSizes = new int[size];
			for (int i = 0; i < size; i++) {
				colnames[i] = rsmd.getColumnName(i + 1);
				colTypes[i] = rsmd.getColumnTypeName(i + 1);
				colSizes[i] = rsmd.getColumnDisplaySize(i + 1);
			}

			String content = parse(colnames, colTypes, colSizes);

			try {
				
				String classPath ="";
				int targetIndex = targetClassPath.indexOf("/target");
				if(targetIndex>0){
					classPath = targetClassPath.substring(0, targetIndex) + "/src/main/java/";
				}else{
					targetIndex = targetClassPath.indexOf("/bin");
					classPath= targetClassPath.substring(0, targetIndex)+"/src/";
				}
				
				String outputPath = classPath + this.packageOutPath.replace(".", "/") + "/" + initcap(tablename) + ".java";

				System.out.println("创建的文件物理路径：" + outputPath);
				File outFile = new File(outputPath);
				if(!outFile.getParentFile().exists()){
					outFile.getParentFile().mkdirs();
				}
				if(outFile.exists()){
					System.out.println("实体已经存在为防止覆盖失误，请自己删除后再重新生成!");
					throw new RuntimeException("阻止生成.");
				}
				FileWriter fw = new FileWriter(outputPath);
				PrintWriter pw = new PrintWriter(fw);
				pw.println(content);
				pw.flush();
				pw.close();
				
				
				String[] tableNames = null;
				if(tablename.indexOf("_")!=-1){
					tableNames = tablename.split("_");
					StringBuffer bf = new StringBuffer(tableNames[0]);
					for(int p=1;p<tableNames.length;p++){
						bf.append(initcap(tableNames[p]));
					}
					tablename = bf.toString();
				}
				
				System.out.println(packageOutPath+"." + initcap(tablename) +" 创建成功请检查!");
			} catch (IOException e) {
				e.printStackTrace();
			}

		} catch (SQLException e) {
			e.printStackTrace();
		} finally {
			// try {
			// con.close();
			// } catch (SQLException e) {
			// // TODO Auto-generated catch block
			// e.printStackTrace();
			// }
		}
	}

	/**
	 * 功能：生成实体类主体代码
	 * 
	 * @param colnames
	 * @param colTypes
	 * @param colSizes
	 * @return
	 */
	private String parse(String[] colnames, String[] colTypes, int[] colSizes) {
		StringBuffer sb = new StringBuffer();
		
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");// 设置格式化格式
		String nowDate = sdf.format(new Date());
		
		// 判断是否导入工具包
		if (f_util) {
			sb.append("import java.util.Date;\r\n");
		}
		if (f_sql) {
			sb.append("import java.sql.*;\r\n");
		}
		sb.append("package " + this.packageOutPath + ";\r\n");
		sb.append("\r\n");
		// 注释部分
		sb.append("/**\r\n");
		sb.append(" * " + functionDetail + "\r\n");
		sb.append(" * @author" + " " + this.authorName + " \r\n");
		
		sb.append(" * @date" + " " + nowDate + "\r\n");
		sb.append(" * "+ copyright +" \r\n");
		sb.append(" */ \r\n");
		
		// 实体部分
		String[] tableNames = null;
		if(tablename.indexOf("_")!=-1){
			tableNames = tablename.split("_");
			StringBuffer bf = new StringBuffer(tableNames[0]);
			for(int p=1;p<tableNames.length;p++){
				bf.append(initcap(tableNames[p]));
			}
			tablename = bf.toString();
		}
		sb.append("\npublic class " + initcap(tablename) + "{\r\n");
		sb.append("\n");
		processAllAttrs(sb);// 属性
		processAllMethod(sb);// get set方法
		sb.append("}\r\n");
		return sb.toString();
	}

	/**
	 * 功能：生成所有属性
	 * 
	 * @param sb
	 */
	private void processAllAttrs(StringBuffer sb) {

		for (int i = 0; i < colnames.length; i++) {
			String colName = colnames[i];
			String[] colNames = null;
			if(colName.indexOf("_")!=-1){
				colNames = colName.split("_");
				StringBuffer bf = new StringBuffer(colNames[0]);
				for(int p=1;p<colNames.length;p++){
					bf.append(initcap(colNames[p]));
				}
				colName = bf.toString();
				colnames[i] = colName;
			}
			sb.append("\tprivate " + sqlType2JavaType(colTypes[i]) + " " + colName + ";\r\n");
		}
		sb.append("\n");
	}

	/**
	 * 功能：生成所有方法
	 * 
	 * @param sb
	 */
	private void processAllMethod(StringBuffer sb) {

		for (int i = 0; i < colnames.length; i++) {
			sb.append("\tpublic void set" + initcap(colnames[i]) + "("
					+ sqlType2JavaType(colTypes[i]) + " " + colnames[i]
					+ "){\r\n");
			sb.append("\t\tthis." + colnames[i] + "=" + colnames[i] + ";\r\n");
			sb.append("\t}\r\n\n");
			sb.append("\tpublic " + sqlType2JavaType(colTypes[i]) + " get"
					+ initcap(colnames[i]) + "(){\r\n");
			sb.append("\t\treturn " + colnames[i] + ";\r\n");
			sb.append("\t}\r\n\n");
		}

	}

	/**
	 * 功能：将输入字符串的首字母改成大写
	 * 
	 * @param str
	 * @return
	 */
	private String initcap(String str) {

		char[] ch = str.toCharArray();
		if (ch[0] >= 'a' && ch[0] <= 'z') {
			ch[0] = (char) (ch[0] - 32);
		}
		return new String(ch);
	}

	/**
	 * 功能：获得列的数据类型
	 * 
	 * @param sqlType
	 * @return
	 */
	private String sqlType2JavaType(String sqlType) {
		sqlType = sqlType.toUpperCase();
		if (sqlType.indexOf("BIT")!=-1) {
			return "Boolean";
		} else if (sqlType.indexOf("TINYINT")!=-1) {
			return "Byte";
		} else if (sqlType.indexOf("SMALLINT")!=-1) {
			return "Short";
		} else if (sqlType.indexOf("BIGINT")!=-1) {
			return "Long";
		} else if (sqlType.indexOf("INT")!=-1) {
			return "Integer";
		} else if (sqlType.indexOf("FLOAT")!=-1) {
			return "Float";
		} else if (sqlType.indexOf("DOUBLE")!=-1 || sqlType.indexOf("DECIMAL")!=-1
				|| sqlType.indexOf("NUMERIC")!=-1
				|| sqlType.indexOf("REAL")!=-1
				|| sqlType.indexOf("MONEY")!=-1
				|| sqlType.indexOf("SMALLMONEY")!=-1) {
			return "Double";
		} else if (sqlType.indexOf("VARCHAR")!=-1
				|| sqlType.indexOf("CHAR")!=-1
				|| sqlType.indexOf("NVARCHAR")!=-1
				|| sqlType.indexOf("NCHAR")!=-1
				|| sqlType.indexOf("TEXT")!=-1) {
			if(sqlType.indexOf("TEXT")!=-1){
				f_sql = true;
			}
			return "String";
		} else if (sqlType.indexOf("DATETIME")!=-1) {
			f_util = true;
			return "Date";
		} else if (sqlType.indexOf("IMAGE")!=-1) {
			f_sql = true;
			return "Blod";
		}
		return null;
	}

	/**
	 * 执行
	 * @param args
	 */
	public static void main(String[] args) {
		new GenerateEntity();
	}

}
